#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
#   \\  /    A nd           | Copyright (C) 2011-2021 OpenFOAM Foundation
#    \\/     M anipulation  |
#------------------------------------------------------------------------------
# License
#     This file is part of OpenFOAM.
#
#     OpenFOAM is free software: you can redistribute it and/or modify it
#     under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#     for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
#
# Script
#     Allwmake
#
# Description
#     Build script for ThirdParty
#
#------------------------------------------------------------------------------
# run from third-party directory only
cd ${0%/*} || exit 1
wmakeCheckPwd "$WM_THIRD_PARTY_DIR" || {
    echo "Error: Current directory is not \$WM_THIRD_PARTY_DIR"
    echo "    The environment variables are inconsistent with the installation."
    echo "    Check the OpenFOAM entries in your dot-files and source them."
    exit 1
}
[ -n "$FOAM_EXT_LIBBIN" ] || {
    echo "Error: FOAM_EXT_LIBBIN not set"
    echo "    Check the OpenFOAM entries in your dot-files and source them."
    exit 1
}
. etc/tools/ThirdPartyFunctions
#------------------------------------------------------------------------------

# export WM settings in a form that GNU configure recognizes
[ -n "$WM_CC" ]         &&  export CC="$WM_CC"
[ -n "$WM_CXX" ]        &&  export CXX="$WM_CXX"
[ -n "$WM_CFLAGS" ]     &&  export CFLAGS="$WM_CFLAGS"
[ -n "$WM_CXXFLAGS" ]   &&  export CXXFLAGS="$WM_CXXFLAGS"
[ -n "$WM_LDFLAGS" ]    &&  export LDFLAGS="$WM_LDFLAGS"

echo
echo ========================================
echo Start ThirdParty Allwmake
echo ========================================
echo

#------------------------------------------------------------------------------

echo ========================================
echo Build MPI libraries if required
case "$WM_MPLIB" in
OPENMPI)
    if [ -r $MPI_ARCH_PATH/lib${WM_COMPILER_LIB_ARCH}/libmpi.so ] ||
       [ -r $MPI_ARCH_PATH/lib/libmpi.so ]
    then
        echo "    have $WM_MPLIB shared library ($FOAM_MPI)"
    elif [ -r $MPI_ARCH_PATH/lib${WM_COMPILER_LIB_ARCH}/libmpi.a ] ||
         [ -r $MPI_ARCH_PATH/lib/libmpi.a ]
    then
        echo "    have $WM_MPLIB static library ($FOAM_MPI)"
    else
    (
        set -x
        cd "${MPI_ARCH_PATH##*/}" || exit 1

        [ -e Makefile ] && make distclean 2>/dev/null
        rm -rf $MPI_ARCH_PATH

        configOpt=

        # GridEngine support
        configOpt="$configOpt --with-sge"

        # Infiniband support
        if [ -n "$MPI_OFED_DIR" ]
        then
            configOpt="$configOpt --with-openib=$MPI_OFED_DIR"
            configOpt="$configOpt --with-openib-libdir=${MPI_OFED_LIB_DIR:-$MPI_OFED_DIR/lib}"
        fi

        ./configure \
            --prefix=$MPI_ARCH_PATH \
            --disable-orterun-prefix-by-default \
            --enable-shared \
            --disable-static \
            --enable-mpi-thread-multiple \
            --libdir=$MPI_ARCH_PATH/lib${WM_COMPILER_LIB_ARCH} \
            --enable-mpi-fortran=none \
            --disable-mpi-profile \
            $configOpt \
            ;

        make -j $WM_NCOMPPROCS && make install
        make distclean
    )
    fi
    ;;

MPICH)
    if [ -r $MPI_ARCH_PATH/lib${WM_COMPILER_LIB_ARCH}/libmpich.so ] ||
       [ -r $MPI_ARCH_PATH/lib/libmpich.so ]
    then
        echo "    have $WM_MPLIB shared library ($FOAM_MPI)"
    elif [ -r $MPI_ARCH_PATH/lib${WM_COMPILER_LIB_ARCH}/libmpich.a ] ||
         [ -r $MPI_ARCH_PATH/lib/libmpich.a ]
    then
        echo "    have $WM_MPLIB static library ($FOAM_MPI)"
    else
    (
        set -x
        cd $WM_THIRD_PARTY_DIR/$FOAM_MPI || exit 1

        [ -e Makefile ] && make distclean 2>/dev/null
        rm -rf $MPI_ARCH_PATH

        ./configure \
            --prefix=$MPI_ARCH_PATH \
            --without-mpe \
            --disable-fortran \
            --disable-mpedbg \
            --disable-devdebug \
            --disable-debug \
            --enable-sharedlib=$MPI_ARCH_PATH/lib \
            ;

        make -j $WM_NCOMPPROCS && make install
        make distclean
    )
    fi
    ;;

esac
echo


#------------------------------------------------------------------------------

mplibVariable()
{
    make --no-print-directory \
    "GENERAL_RULES=\$(WM_DIR)/rules/General" \
    --file="$WM_DIR/rules/General/mplibType" \
    --eval="print-variable:
	@echo \$($1)" print-variable
}


#------------------------------------------------------------------------------

checkSystemLibrary()
{
    libraryName=$1
    includeName=$2
    reportName=$3

    if ! \
        $CXX $LDFLAGS -shared --output=/dev/null ${4:+"-L$4"} -l$libraryName \
        > /dev/null 2>&1
    then
        echo -n "    Error: A system installation of the $reportName library "
        echo "(lib$libraryName.so) was not found"
        exit 1
    fi

    if ! echo \#include \"$includeName.h\" | \
        $CXX $CXXFLAGS ${5:+"-I$5"} $(mplibVariable PINC) -xc++ -E - \
        > /dev/null 2>&1
    then
        echo -n "    Error: A system installation of $reportName headers "
        echo "($includeName.h) was not found"
        exit 1
    fi
}


#------------------------------------------------------------------------------

# Scotch

# Scotch Makefile. Currently this is GCC specific.
scotchMakefile=../../etc/wmakeFiles/scotch/Makefile.inc.i686_pc_linux2.shlib-OpenFOAM

echo ========================================
case $SCOTCH_TYPE in
none)
    echo "Scotch decomposition is disabled"
    ;;
system)
    echo "The system installation of Scotch decomposition will be used"
    checkSystemLibrary scotch scotch Scotch \
        "$SCOTCH_LIB_DIR" "${SCOTCH_INCLUDE_DIR:-/usr/include/scotch}"
    ;;
OpenFOAM | ThirdParty)
    . $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/scotch)
    if [ -f $SCOTCH_ARCH_PATH/include/scotch.h \
      -a -r $FOAM_EXT_LIBBIN/libscotch.so \
      -a -r $FOAM_EXT_LIBBIN/libscotcherrexit.so ]
    then
        echo "ThirdParty installation of Scotch decomposition found"
        echo "    scotch header in $SCOTCH_ARCH_PATH/include"
        echo "    scotch libs   in $FOAM_EXT_LIBBIN"
    else
        if [ -d "scotch_$SCOTCH_VERSION" ]
        then
        (
            echo "Building a ThirdParty installation of Scotch decomposition"

            set -x
            cd scotch_$SCOTCH_VERSION/src || exit 1

            prefixDIR=$SCOTCH_ARCH_PATH
            libDIR=$FOAM_EXT_LIBBIN

            mkdir -p $prefixDIR 2>/dev/null
            mkdir -p $libDIR 2>/dev/null

            configOpt="prefix=$prefixDIR libdir=$libDIR"

            if [ -f $scotchMakefile ]
            then
                rm -f Makefile.inc
                ln -s $scotchMakefile Makefile.inc
            fi

            [ -f Makefile.inc ] || {
                echo "    Error: scotch needs an appropriate Makefile.inc"
                exit 1
            }

            # handle non-gcc compilers
            unset configEnv
            [ "${WM_CC:-gcc}" != gcc ] && configEnv="CC=$WM_CC CCS=$WM_CC"

            make realclean 2>/dev/null  # for safety

            make -j $WM_NCOMPPROCS $configEnv scotch \
            && make $configOpt install

            # cleanup, could also remove Makefile.inc
            make realclean 2>/dev/null
        )
        else
            echo -n "    Error: ThirdPaty sources for Scotch "
            echo "(scotch_$SCOTCH_VERSION) were not found"
            exit 1
        fi
    fi

    # verify existence of scotch include
    [ -f $SCOTCH_ARCH_PATH/include/scotch.h ] || {
        echo
        echo "    WARNING: required include file 'scotch.h' not found!"
    }
    ;;
esac
echo

#------------------------------------------------------------------------------

# PT-Scotch if MPI (ThirdParty or system) is available

if [ "${FOAM_MPI:-dummy}" != dummy ]
then
    echo ========================================
    case $SCOTCH_TYPE in
    none)
        echo "PT-Scotch decomposition is disabled"
        ;;
    system)
        echo "The system installation of PT-Scotch decomposition will be used"
        checkSystemLibrary ptscotch ptscotch PT-Scotch \
            "$PTSCOTCH_LIB_DIR" "${PTSCOTCH_INCLUDE_DIR:-/usr/include/scotch}"
        ;;
    OpenFOAM | ThirdParty)
        . $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/scotch)
        if [ -f $SCOTCH_ARCH_PATH/include/$FOAM_MPI/ptscotch.h \
          -a -r $FOAM_EXT_LIBBIN/$FOAM_MPI/libptscotch.so \
          -a -r $FOAM_EXT_LIBBIN/$FOAM_MPI/libptscotcherrexit.so ]
        then
            echo "ThirdParty installation of PT-Scotch decomposition found"
            echo "    ptscotch header in $SCOTCH_ARCH_PATH/include/$FOAM_MPI"
            echo "    ptscotch libs   in $FOAM_EXT_LIBBIN/$FOAM_MPI"
        else
            if [ -d "scotch_$SCOTCH_VERSION" ]
            then
            (
                echo "Building a ThirdParty installation of PT-Scotch decomposition"

                set -x
                cd scotch_$SCOTCH_VERSION/src || exit 1

                prefixDIR=$SCOTCH_ARCH_PATH
                libDIR=$FOAM_EXT_LIBBIN/$FOAM_MPI
                incDIR=$SCOTCH_ARCH_PATH/include/$FOAM_MPI

                mkdir -p $prefixDIR 2>/dev/null
                mkdir -p $libDIR 2>/dev/null

                configOpt="prefix=$prefixDIR libdir=$libDIR includedir=$incDIR"

                if [ -f $scotchMakefile ]
                then
                    rm -f Makefile.inc
                    ln -s $scotchMakefile Makefile.inc
                fi

                [ -f Makefile.inc ] || {
                    echo "    Error: scotch needs an appropriate Makefile.inc"
                    exit 1
                }

                # handle non-gcc compilers
                unset configEnv
                [ "${WM_CC:-gcc}" != gcc ] && configEnv="CC=$WM_CC CCS=$WM_CC"

                make realclean 2>/dev/null  # for safety

                make -j $WM_NCOMPPROCS $configEnv ptscotch \
                && make $configOpt install

                # cleanup, could also remove Makefile.inc
                make realclean 2>/dev/null
            )
            else
                echo -n "    Error: ThirdPaty sources for PT-Scotch "
                echo "(scotch_$SCOTCH_VERSION) were not found"
                exit 1
            fi
        fi

        # Verify existence of PT-Scotch include
        [ -f $SCOTCH_ARCH_PATH/include/$FOAM_MPI/ptscotch.h ] || {
            echo
            echo "    WARNING: required include file 'ptscotch.h' not found!"
        }
        ;;
    esac
fi
echo

#------------------------------------------------------------------------------

# METIS

echo ========================================
case $METIS_TYPE in
none)
    echo "METIS decomposition is disabled"
    ;;
system)
    echo "The system installation of METIS decomposition will be used"
    checkSystemLibrary metis metis METIS \
        "$METIS_LIB_DIR" "$METIS_INCLUDE_DIR"
    ;;
OpenFOAM | ThirdParty)
    . $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/metis)
    if [ -f $METIS_ARCH_PATH/include/metis.h \
      -a -r $FOAM_EXT_LIBBIN/libmetis.so ]
    then
        echo "ThirdParty installation of METIS decomposition found"
        echo "    metis header in $METIS_ARCH_PATH/include"
        echo "    metis libs   in $FOAM_EXT_LIBBIN"
    else
        if [ -d "metis-$METIS_VERSION" ]
        then
        (
            echo "Building a ThirdParty installation of METIS decomposition"

            set -x
            cd metis-$METIS_VERSION  || exit 1

            # Change user settings automatically
            sed -i -e 's=\(#define IDXTYPEWIDTH\).*=\1 '$WM_LABEL_SIZE'=' \
                include/metis.h

            make config shared=1 prefix=$METIS_ARCH_PATH
            make -j $WM_NCOMPPROCS install
            cp $METIS_ARCH_PATH/lib/libmetis.so $FOAM_EXT_LIBBIN
        )
        else
            echo -n "    Error: ThirdPaty sources for METIS "
            echo "(metis-$METIS_VERSION) were not found"
            exit 1
        fi
    fi
    ;;
esac
echo

#------------------------------------------------------------------------------

# ParMETIS

echo ========================================
case $PARMETIS_TYPE in
none)
    echo "ParMETIS decomposition is disabled"
    ;;
system)
    echo "The system installation of ParMETIS decomposition will be used"
    checkSystemLibrary parmetis parmetis ParMETIS \
        "$PARMETIS_LIB_DIR" "$PARMETIS_INCLUDE_DIR"
    ;;
OpenFOAM | ThirdParty)
    . $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/parMetis)
    if [ -f $PARMETIS_ARCH_PATH/include/parmetis.h \
      -a -r $FOAM_EXT_LIBBIN/libparmetis.so ]
    then
        echo "ThirdParty installation of ParMETIS decomposition found"
        echo "    parmetis header in $PARMETIS_ARCH_PATH/include"
        echo "    parmetis libs   in $FOAM_EXT_LIBBIN"
    else
        echo "Building a ThirdParty installation of ParMETIS decomposition"
        if [ -d "parmetis-$PARMETIS_VERSION" ]
        then
        (
            set -x
            cd parmetis-$PARMETIS_VERSION  || exit 1

            # Change user settings automatically
            sed -i -e 's=\(#define IDXTYPEWIDTH\).*=\1 '$WM_LABEL_SIZE'=' \
                metis/include/metis.h

            make config shared=1 prefix=$PARMETIS_ARCH_PATH
            make -j $WM_NCOMPPROCS install
            cp metis/include/metis.h $PARMETIS_ARCH_PATH/include
            cp $PARMETIS_ARCH_PATH/lib/libparmetis.so $FOAM_EXT_LIBBIN
        )
        else
            echo -n "    Error: ThirdPaty sources for ParMETIS "
            echo "(parmetis-$PARMETIS_VERSION) were not found"
            exit 1
        fi
    fi
    ;;
esac
echo

#------------------------------------------------------------------------------

echo ========================================
case $ZOLTAN_TYPE in
none)
    echo "Zoltan decomposition is disabled"
    ;;
system)
    echo "The system installation of Zoltan decomposition will be used"
    checkSystemLibrary zoltan zoltan Zoltan \
        "$ZOLTAN_LIB_DIR" "$ZOLTAN_INCLUDE_DIR"
    ;;
OpenFOAM | ThirdParty)
    . $($WM_PROJECT_DIR/bin/foamEtcFile config.sh/zoltan)
    if [ -f $ZOLTAN_ARCH_PATH/include/zoltan.h \
      -a -r $FOAM_EXT_LIBBIN/$FOAM_MPI/libzoltan.a ]
    then
        echo "ThirdParty installation of Zoltan decomposition found"
        echo "    Zoltan header in $ZOLTAN_ARCH_PATH/include"
        echo "    Zoltan libs   in $FOAM_EXT_LIBBIN/$FOAM_MPI"
    else
        echo "Building a ThirdParty installation of Zoltan decomposition"
        if [ -d "Zoltan-$ZOLTAN_VERSION" ]
        then
        (
            set -x
            cd Zoltan-$ZOLTAN_VERSION  || exit 1
            mkdir -p build
            cd build
            ../configure \
                --prefix=$ZOLTAN_ARCH_PATH \
                --libdir=$FOAM_EXT_LIBBIN/$FOAM_MPI \
                --enable-mpi=yes \
                --with-mpi-compilers=no \
                --with-mpi-incdir="$(mplibVariable PINC \
                | grep -o '\(-isystem[ ]\+\|-I\)[^ ]\+' \
                | tr '\n' ' ' \
                | sed 's/\(-isystem[ ]\+\|-I\)//')" \
                --with-mpi-libs="$(mplibVariable PLIBS)" \
                --disable-zoltan-cppdriver \
                --with-ccflags=-fPIC \
                --with-cxxflags=-fPIC
            make everything
            make install
        )
        else
            echo -n "    Error: ThirdPaty sources for Zoltan "
            echo "(Zoltan-$ZOLTAN_VERSION) were not found"
            exit 1
        fi
    fi
    ;;
esac
echo


#------------------------------------------------------------------------------

echo ========================================
echo Done ThirdParty Allwmake
echo ========================================
echo

#------------------------------------------------------------------------------
